#include "network.h"
#include "utils_log.h"
#include "common_config_manager.h"
#include <fstream>
#include <sstream>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <regex>
#include <set>
#include "ntp_manager.h"

namespace El {
namespace Network {

Network& Network::GetInstance()
{
    static Network instance;
    return instance;
}

Network::Network() : initialized_(false), config_apply_listener_id_(-1), config_verify_listener_id_(-1)
{
}

bool Network::Start()
{
    std::lock_guard<std::mutex> lock(mutex_);
    
    if (initialized_) {
        EL_INFO("Network module already initialized");
        return true;
    }
    
    EL_INFO("Initializing network module");
    
    // 加载网络配置
    if (!LoadConfig()) {
        EL_ERROR("Failed to load network configuration");
        return false;
    }
    
    // 生成interfaces文件
    if (!GenerateInterfacesFile()) {
        EL_ERROR("Failed to generate interfaces file");
        return false;
    }
    
    // 应用DNS配置
    if (!ApplyDnsConfig()) {
        EL_ERROR("Failed to apply DNS configuration");
        return false;
    }
    
    // 应用主机名配置
    if (!ApplyHostname()) {
        EL_ERROR("Failed to apply hostname configuration");
        return false;
    }
    
    // 启动NTP服务
    if (!NtpManager::GetInstance().Start()) {
        EL_ERROR("Failed to start NTP service");
        return false;
    }
    
    // 注册配置变更监听器
    auto& configManager = Common::ConfigManager::GetInstance();
    config_apply_listener_id_ = configManager.Register(CONFIG_PATH, [this](const nlohmann::json& config) -> bool {
        OnConfigChanged(CONFIG_PATH, config);
        return true;
    }, Common::ConfigPriority::APPLY);

    config_verify_listener_id_ = configManager.Register(CONFIG_PATH, [this](const nlohmann::json& config) -> bool {
        // 验证网络配置的合法性
        if (!ValidateNetworkConfig(config)) {
            EL_ERROR("Network configuration validation failed");
            return false;
        }
        return true;
    }, Common::ConfigPriority::VERIFY);
    
    initialized_ = true;
    EL_INFO("Network module initialization completed");
    
    return true;
}

void Network::Destroy()
{
    std::lock_guard<std::mutex> lock(mutex_);
    
    if (!initialized_) {
        return;
    }
    
    EL_INFO("Destroying network module");
    
    // 取消注册配置监听器
    auto& configManager = Common::ConfigManager::GetInstance();
    if (config_apply_listener_id_ != -1) {
        configManager.Unregister(CONFIG_PATH, config_apply_listener_id_);
        config_apply_listener_id_ = -1;
    }

    if (config_verify_listener_id_ != -1) {
        configManager.Unregister(CONFIG_PATH, config_verify_listener_id_);
        config_verify_listener_id_ = -1;
    }
    
    initialized_ = false;
}

bool Network::LoadConfig()
{
    auto& configManager = Common::ConfigManager::GetInstance();
    config_ = configManager.GetConfig(CONFIG_PATH);
    return ValidateNetworkConfig(config_);
}

bool Network::SaveConfig()
{
    auto& configManager = Common::ConfigManager::GetInstance();
    return configManager.SetConfig(CONFIG_PATH, config_);
}

nlohmann::json Network::GetNetworkConfig() const
{
    std::lock_guard<std::mutex> lock(mutex_);
    return config_;
}

bool Network::SetNetworkConfig(const nlohmann::json& config)
{
    std::lock_guard<std::mutex> lock(mutex_);
    
    if (!ValidateNetworkConfig(config)) {
        EL_ERROR("Network configuration validation failed");
        return false;
    }
    
    config_ = config;
    
    // 保存配置
    auto& configManager = Common::ConfigManager::GetInstance();
    if (!configManager.SetConfig(CONFIG_PATH, config_)) {
        EL_ERROR("Failed to save network configuration");
        return false;
    }
    
    EL_INFO("Network configuration updated");
    return true;
}

void Network::OnConfigChanged(const std::string& path, const nlohmann::json& config)
{
    EL_INFO("Network configuration changed: {}", path);
    
    // 异步处理配置变更，避免死锁
    // 不在这里获取锁，而是启动一个异步任务
    std::thread([this, path, config]() {
        // 增加延迟
        std::this_thread::sleep_for(std::chrono::milliseconds(200));
        ProcessConfigChangeAsync(path, config);
    }).detach();
}

void Network::ProcessConfigChangeAsync(const std::string& path, const nlohmann::json& config)
{
    EL_INFO("Starting async processing of network configuration change: {}", path);
    
    // 更新配置（在锁保护下）
    {
        std::lock_guard<std::mutex> lock(mutex_);
        config_ = config;
    }
    
    // 在锁外执行可能阻塞的操作
    // 重新生成interfaces文件
    if (!GenerateInterfacesFile()) {
        EL_ERROR("Failed to regenerate interfaces file");
        return;
    }
    
    // 重新应用DNS和主机名配置
    ApplyDnsConfig();
    ApplyHostname();
    
    // 重启所有启用的网络接口
    if (config.contains("interfaces")) {
        for (const auto& [interface_name, interface_config] : config["interfaces"].items()) {
            if (interface_config.contains("enable") && interface_config["enable"].get<bool>()) {
                RestartInterface(interface_name);
            }
        }
    }
    
    EL_INFO("Async processing of network configuration change completed: {}", path);
}

bool Network::ValidateNetworkConfig(const nlohmann::json& config) const
{
    if (!config.contains("interfaces")) {
        EL_ERROR("Network configuration missing interfaces field");
        return false;
    }
    
    if (!config["interfaces"].is_object()) {
        EL_ERROR("interfaces field must be an object");
        return false;
    }
    
    // 验证每个接口配置
    for (const auto& [interface_name, interface_config] : config["interfaces"].items()) {
        if (!ValidateInterfaceConfig(interface_name, interface_config)) {
            return false;
        }
    }
    
    // 验证DNS配置
    if (config.contains("dns") && !config["dns"].is_array()) {
        EL_ERROR("dns field must be an array");
        return false;
    }
    
    return true;
}

bool Network::ValidateInterfaceConfig(const std::string& interface, const nlohmann::json& config) const
{
    if (!config.contains("enable") || !config["enable"].is_boolean()) {
        EL_ERROR("Interface {} missing enable field or type error", interface);
        return false;
    }
    
    if (!config.contains("type") || !config["type"].is_string()) {
        EL_ERROR("Interface {} missing type field or type error", interface);
        return false;
    }
    
    if (!config.contains("mode") || !config["mode"].is_string()) {
        EL_ERROR("Interface {} missing mode field or type error", interface);
        return false;
    }
    
    std::string mode = config["mode"];
    if (mode != "dhcp" && mode != "static") {
        EL_ERROR("Interface {} mode field must be dhcp or static", interface);
        return false;
    }
    
    // 静态IP模式需要验证ipv4配置
    if (mode == "static") {
        if (!config.contains("ipv4") || !config["ipv4"].is_object()) {
            EL_ERROR("Static IP mode interface {} missing ipv4 configuration", interface);
            return false;
        }

        const auto& ipv4 = config["ipv4"];
        if (!ipv4.contains("address") || !ipv4.contains("netmask") || !ipv4.contains("gateway")) {
            EL_ERROR("Interface {} ipv4 configuration missing required fields", interface);
            return false;
        }

        // 验证IP地址、子网掩码和网关的合法性
        if (ipv4.contains("address") && !IsValidIpAddress(ipv4["address"].get<std::string>())) {
            EL_ERROR("Interface {} has invalid IP address: {}", interface, ipv4["address"].get<std::string>());
            return false;
        }

        if (ipv4.contains("netmask") && !IsValidNetmask(ipv4["netmask"].get<std::string>())) {
            EL_ERROR("Interface {} has invalid netmask: {}", interface, ipv4["netmask"].get<std::string>());
            return false;
        }

        if (ipv4.contains("gateway") && !IsValidGateway(ipv4["gateway"].get<std::string>())) {
            EL_ERROR("Interface {} has invalid gateway: {}", interface, ipv4["gateway"].get<std::string>());
            return false;
        }
    }
    
    return true;
}

bool Network::GenerateInterfacesFile()
{
    std::string content = GetInterfacesFileContent();
    return WriteInterfacesFile(content);
}

std::string Network::GetInterfacesFileContent() const
{
    std::ostringstream oss;
    
    // 添加loopback接口
    oss << "# Generated by Network Module\n";
    oss << "auto lo\n";
    oss << "iface lo inet loopback\n\n";
    
    // 添加配置的网络接口
    if (config_.contains("interfaces")) {
        for (const auto& [interface_name, interface_config] : config_["interfaces"].items()) {
            if (!interface_config.contains("enable") || !interface_config["enable"].get<bool>()) {
                oss << "# Interface " << interface_name << " is disabled\n";
                continue;
            }
            
            oss << "auto " << interface_name << "\n";
            
            std::string mode = interface_config.value("mode", "dhcp");
            if (mode == "dhcp") {
                oss << "iface " << interface_name << " inet dhcp\n\n";
            } else if (mode == "static") {
                oss << "iface " << interface_name << " inet static\n";
                
                if (interface_config.contains("ipv4")) {
                    const auto& ipv4 = interface_config["ipv4"];
                    if (ipv4.contains("address")) {
                        oss << "    address " << ipv4["address"].get<std::string>() << "\n";
                    }
                    if (ipv4.contains("netmask")) {
                        oss << "    netmask " << ipv4["netmask"].get<std::string>() << "\n";
                    }
                    if (ipv4.contains("gateway")) {
                        oss << "    gateway " << ipv4["gateway"].get<std::string>() << "\n";
                    }
                }
                oss << "\n";
            }
        }
    }
    
    return oss.str();
}

bool Network::WriteInterfacesFile(const std::string& content)
{
    // 确保目录存在
    std::string dir = "/mnt/config";
    if (access(dir.c_str(), F_OK) != 0) {
        if (mkdir(dir.c_str(), 0755) != 0) {
            EL_ERROR("Failed to create directory: {}", dir);
            return false;
        }
    }
    
    // 写入临时文件，然后原子性地移动到目标位置
    std::string temp_file = std::string(INTERFACES_FILE_PATH) + ".tmp";
    
    std::ofstream file(temp_file);
    if (!file.is_open()) {
        EL_ERROR("Unable to create temporary interfaces file: {}", temp_file);
        return false;
    }
    
    file << content;
    file.close();
    
    // 原子性地移动文件
    if (rename(temp_file.c_str(), INTERFACES_FILE_PATH) != 0) {
        EL_ERROR("Failed to move interfaces file: {} -> {}", temp_file, INTERFACES_FILE_PATH);
        unlink(temp_file.c_str());
        return false;
    }
    
    EL_INFO("Network interfaces configured");
    return true;
}

bool Network::ApplyDnsConfig()
{
    if (!config_.contains("dns") || !config_["dns"].is_array()) {
        EL_INFO("No DNS configuration or DNS configuration is empty");
        return true;
    }
    
    std::ostringstream oss;
    oss << "# Generated by Network Module\n";
    
    for (const auto& dns : config_["dns"]) {
        if (dns.is_string() && !dns.get<std::string>().empty()) {
            oss << "nameserver " << dns.get<std::string>() << "\n";
        }
    }
    
    std::ofstream file(RESOLV_CONF_PATH);
    if (!file.is_open()) {
        EL_ERROR("Unable to write DNS configuration file: {}", RESOLV_CONF_PATH);
        return false;
    }
    
    file << oss.str();
    file.close();
    
    EL_INFO("DNS servers configured");
    return true;
}

bool Network::ApplyHostname()
{
    std::string hostname = config_.value("hostname", "endless");
    
    // 暂时不支持主机名修改，保留系统默认设置
    EL_INFO("Hostname configuration keeps system default settings, no modification. Hostname in config: {}", hostname);
    
    return true;
}

bool Network::ConfigureNetworkDhcp(const std::string& interface)
{
    EL_INFO("Configuring interface {} in DHCP mode", interface);
    
    // 更新配置（在锁保护下）
    {
        std::lock_guard<std::mutex> lock(mutex_);
        
        if (!config_["interfaces"].contains(interface)) {
            config_["interfaces"][interface] = nlohmann::json::object();
        }
        
        config_["interfaces"][interface]["enable"] = true;
        config_["interfaces"][interface]["type"] = "ethernet";
        config_["interfaces"][interface]["mode"] = "dhcp";
    }
    
    // 在锁外执行可能阻塞的操作
    // 保存配置
    if (!SaveConfig()) {
        EL_ERROR("Failed to save DHCP configuration");
        return false;
    }
    
    // 重新生成interfaces文件
    if (!GenerateInterfacesFile()) {
        EL_ERROR("Failed to regenerate interfaces file");
        return false;
    }
    
    // 重启接口
    return RestartInterface(interface);
}

bool Network::ConfigureNetworkStatic(const std::string& interface,
                                     const std::string& address,
                                     const std::string& netmask,
                                     const std::string& gateway)
{
    EL_INFO("Configuring interface {} in static IP mode: {}/{} via {}", interface, address, netmask, gateway);

    // 验证IP地址、子网掩码和网关的合法性
    if (!IsValidIpAddress(address)) {
        EL_ERROR("Invalid IP address: {}", address);
        return false;
    }

    if (!IsValidNetmask(netmask)) {
        EL_ERROR("Invalid netmask: {}", netmask);
        return false;
    }

    if (!IsValidGateway(gateway)) {
        EL_ERROR("Invalid gateway: {}", gateway);
        return false;
    }

    // 更新配置（在锁保护下）
    {
        std::lock_guard<std::mutex> lock(mutex_);

        if (!config_["interfaces"].contains(interface)) {
            config_["interfaces"][interface] = nlohmann::json::object();
        }

        config_["interfaces"][interface]["enable"] = true;
        config_["interfaces"][interface]["type"] = "ethernet";
        config_["interfaces"][interface]["mode"] = "static";
        config_["interfaces"][interface]["ipv4"]["address"] = address;
        config_["interfaces"][interface]["ipv4"]["netmask"] = netmask;
        config_["interfaces"][interface]["ipv4"]["gateway"] = gateway;
    }

    // 在锁外执行可能阻塞的操作
    // 保存配置
    if (!SaveConfig()) {
        EL_ERROR("Failed to save static IP configuration");
        return false;
    }

    // 重新生成interfaces文件
    if (!GenerateInterfacesFile()) {
        EL_ERROR("Failed to regenerate interfaces file");
        return false;
    }

    // 重启接口
    return RestartInterface(interface);
}

bool Network::ConfigureDnsServers(const std::string& dns1, const std::string& dns2)
{
    EL_INFO("Configuring DNS servers: {} {}", dns1, dns2);
    
    // 更新配置（在锁保护下）
    {
        std::lock_guard<std::mutex> lock(mutex_);
        
        config_["dns"] = nlohmann::json::array();
        if (!dns1.empty()) {
            config_["dns"].push_back(dns1);
        }
        if (!dns2.empty()) {
            config_["dns"].push_back(dns2);
        }
    }
    
    // 在锁外执行可能阻塞的操作
    // 保存配置
    if (!SaveConfig()) {
        EL_ERROR("Failed to save DNS configuration");
        return false;
    }
    
    // 应用DNS配置
    return ApplyDnsConfig();
}

bool Network::SetHostname(const std::string& hostname)
{
    EL_INFO("Setting hostname: {}", hostname);
    
    // 更新配置（在锁保护下）
    {
        std::lock_guard<std::mutex> lock(mutex_);
        config_["hostname"] = hostname;
    }
    
    // 在锁外执行可能阻塞的操作
    // 保存配置
    if (!SaveConfig()) {
        EL_ERROR("Failed to save hostname configuration");
        return false;
    }
    
    // 应用主机名配置
    return ApplyHostname();
}

bool Network::RestartInterface(const std::string& interface)
{
    EL_INFO("Restarting network interface: {}", interface);
    
    // 先停止接口
    std::string ifdown_cmd = "ifdown " + interface + " 2>/dev/null || true";
    ExecuteCommand(ifdown_cmd);
    
    // 等待一下
    usleep(500000); // 500ms
    
    // 启动接口
    std::string ifup_cmd = "ifup " + interface;
    if (!ExecuteCommand(ifup_cmd)) {
        EL_ERROR("Failed to start network interface: {}", interface);
        return false;
    }
    
    EL_INFO("Network interface {} restart completed", interface);
    return true;
}

bool Network::GetInterfaceStatus(const std::string& interface, nlohmann::json& status)
{
    std::string cmd = "ip addr show " + interface + " 2>/dev/null";
    FILE* pipe = popen(cmd.c_str(), "r");
    if (!pipe) {
        EL_ERROR("Failed to get interface status: {}", interface);
        return false;
    }
    
    char buffer[256];
    std::string result;
    while (fgets(buffer, sizeof(buffer), pipe) != nullptr) {
        result += buffer;
    }
    
    int exit_code = pclose(pipe);
    
    if (exit_code != 0) {
        EL_ERROR("Interface {} does not exist or failed to get status", interface);
        status["exists"] = false;
        return false;
    }
    
    status["exists"] = true;
    status["interface"] = interface;
    
    // 简单解析IP地址
    size_t inet_pos = result.find("inet ");
    if (inet_pos != std::string::npos) {
        size_t start = inet_pos + 5;
        size_t end = result.find(' ', start);
        if (end != std::string::npos) {
            std::string ip_with_mask = result.substr(start, end - start);
            size_t slash_pos = ip_with_mask.find('/');
            if (slash_pos != std::string::npos) {
                status["ip"] = ip_with_mask.substr(0, slash_pos);
                status["cidr"] = ip_with_mask;
            }
        }
    }
    
    // 检查接口是否启动
    status["up"] = result.find("state UP") != std::string::npos;
    
    return true;
}

std::string Network::GetInterfaceIpAddress(const std::string& interface) const
{
    nlohmann::json status;
    if (const_cast<Network*>(this)->GetInterfaceStatus(interface, status) && status.contains("ip")) {
        return status["ip"].get<std::string>();
    }
    return "127.0.0.1"; // 默认返回localhost
}

std::string Network::GetDefaultInterfaceName() const
{
    std::lock_guard<std::mutex> lock(mutex_);
    return config_.value("default_interface", "eth0");
}

std::vector<std::string> Network::GetDnsServers() const
{
    std::lock_guard<std::mutex> lock(mutex_);
    std::vector<std::string> dnsServers;
    
    if (config_.contains("dns") && config_["dns"].is_array()) {
        for (const auto& dns : config_["dns"]) {
            if (dns.is_string()) {
                dnsServers.push_back(dns.get<std::string>());
            }
        }
    }
    
    return dnsServers;
}

std::string Network::GetInterfaceMacAddress(const std::string& interface) const
{
    std::string macAddress;

    // 打开网络接口套接字
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        EL_ERROR("无法创建套接字来获取MAC地址");
        return "00:11:22:33:44:55"; // 返回默认值
    }

    // 使用ioctl获取硬件地址
    struct ifreq ifr;
    std::memset(&ifr, 0, sizeof(ifr));
    std::strncpy(ifr.ifr_name, interface.c_str(), IFNAMSIZ - 1);

    if (ioctl(sockfd, SIOCGIFHWADDR, &ifr) < 0) {
        EL_WARN("无法获取接口 {} 的MAC地址: {}", interface, strerror(errno));
        close(sockfd);
        return "00:11:22:33:44:55"; // 返回默认值
    }

    close(sockfd);

    // 将MAC地址转换为字符串格式
    unsigned char* mac = reinterpret_cast<unsigned char*>(ifr.ifr_hwaddr.sa_data);
    char macStr[18];
    std::snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
                  mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
    macAddress = macStr;

    EL_DEBUG("接口 {} 的MAC地址: {}", interface, macAddress);
    return macAddress;
}

NetIfInfo Network::GetNetworkInterface(const std::string& interface) const
{
    NetIfInfo info;
    info.name = interface;
    
    // 获取接口状态
    nlohmann::json status;
    if (const_cast<Network*>(this)->GetInterfaceStatus(interface, status)) {
        info.status = status.value("up", false) ? NetIfStatus::UP : NetIfStatus::DOWN;
        if (status.contains("ip")) {
            info.ipv4Address = status["ip"].get<std::string>();
            info.hasIpv4 = !info.ipv4Address.empty() && info.ipv4Address != "127.0.0.1";
        }
    }
    
    // 从配置中获取其他信息
    std::lock_guard<std::mutex> lock(mutex_);
    if (config_.contains("interfaces") && 
        config_["interfaces"].contains(interface) &&
        config_["interfaces"][interface].contains("ipv4")) {
        
        const auto& ipv4Config = config_["interfaces"][interface]["ipv4"];
        if (ipv4Config.contains("netmask")) {
            info.ipv4Mask = ipv4Config["netmask"].get<std::string>();
        }
        if (ipv4Config.contains("gateway")) {
            info.gateway = ipv4Config["gateway"].get<std::string>();
        }
    }
    
    // 默认值
    if (info.ipv4Mask.empty()) {
        info.ipv4Mask = "255.255.255.0";
    }
    if (info.gateway.empty()) {
        info.gateway = "192.168.1.1";
    }

    // 获取真实的MAC地址
    info.macAddress = const_cast<Network*>(this)->GetInterfaceMacAddress(interface);

    return info;
}

bool Network::ExecuteCommand(const std::string& command)
{
    EL_INFO("Executing command: {}", command);

    int result = std::system(command.c_str());
    if (result != 0) {
        EL_ERROR("Command execution failed: {}, return code: {}", command, result);
        return false;
    }

    return true;
}

/**
 * @brief 验证IP地址格式是否合法
 * @param ip IP地址字符串
 * @return true表示合法，false表示不合法
 */
bool Network::IsValidIpAddress(const std::string& ip) const
{
    // 使用正则表达式验证IPv4地址格式
    std::regex ipPattern(R"(^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$)");
    return std::regex_match(ip, ipPattern);
}

/**
 * @brief 验证子网掩码是否合法
 * @param netmask 子网掩码字符串
 * @return true表示合法，false表示不合法
 */
bool Network::IsValidNetmask(const std::string& netmask) const
{
    // 首先检查是否是有效的IP地址格式
    if (!IsValidIpAddress(netmask)) {
        return false;
    }

    // 将点分十进制转换为32位整数
    std::istringstream iss(netmask);
    std::string octet;
    uint32_t netmaskBits = 0;
    int shift = 24;

    while (std::getline(iss, octet, '.') && shift >= 0) {
        try {
            int value = std::stoi(octet);
            if (value < 0 || value > 255) {
                return false;
            }
            netmaskBits |= (static_cast<uint32_t>(value) << shift);
            shift -= 8;
        } catch (const std::exception&) {
            return false;
        }
    }

    // 验证子网掩码的有效性：
    // 1. 有效的子网掩码必须是连续的1后跟连续的0
    // 2. 使用位运算检查：mask + (mask ^ 0xFFFFFFFF) + 1 应该是2的幂
    if (netmaskBits == 0) {
        return true; // 0.0.0.0 是有效的掩码
    }

    // 检查是否为连续的1位：通过翻转所有位并加1，结果应该是2的幂
    uint32_t inverted = ~netmaskBits;
    uint32_t check = inverted + 1;

    // 如果check是2的幂，则 check & (check - 1) == 0
    return (check & (check - 1)) == 0;
}

/**
 * @brief 验证网关地址是否合法
 * @param gateway 网关地址字符串
 * @return true表示合法，false表示不合法
 */
bool Network::IsValidGateway(const std::string& gateway) const
{
    // 网关地址验证与IP地址验证相同
    return IsValidIpAddress(gateway);
}

} // namespace Network
} // namespace El